/* shttpd - process all events in a loop
   Copyright (C) 2018 Ariadne Devos

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */

#if 0
/* XXX "worker.h" will be deleted */

#include "worker.h"

#include <sHT/bugs.h>
#include <sHT/compiler.h>

#include <errno.h>
#include <sys/epoll.h>

__attribute__((nonnull (1)))
__attribute__((warn_unused_result))
static int
sHT_wait_and_poll(struct sHT_worker *worker, int timeout)
{
	int n;
	int *err = &errno;
	do n = epoll_wait(worker->watches, worker->epoll_events, worker->todo->capacity, timeout);
	while (sHT_test_hidden(n, n < 0) && sHT_test_hidden(*err, *err == EINTR));
	sHT_require(n >= 0);
	return n;
}

__attribute__((nonnull (1, 2)))
static void
sHT_perform_task_wrapper(void *cookie, struct sHT_task *task)
{
	/* TODO: distinction between homogeneous and heterogeneous */
	sHT_perform_task(cookie, task);
}

__attribute__((nonnull (1)))
static void
sHT_worker_iteration(struct sHT_worker *worker)
{
	/* If there are things to do, do poll, such that other tasks may
	   make progress, but don't wait. */
	_Bool nonblock = sHT_test_hidden(worker->todo->n, worker->todo->n > 0);
	int n_events = sHT_wait_and_poll(worker, nonblock ? 0 : -1);
	sHT_schedule_events(worker, n_events);
	sHT_perform_all(worker, worker->todo, &sHT_perform_task_wrapper);
	/* XXX: notify the control thread (OOM ...) */
	sHT_todo(worker->flags);
}

_Noreturn void
sHT_worker(struct sHT_worker *worker)
{
	while (1)
		sHT_worker_iteration(worker);
}

#endif
